package com.example.points.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.points.domain.PointsDetail;
import com.example.points.domain.UserPoints;
import com.example.points.mapper.PointsDetailMapper;
import com.example.points.mapper.UserPointsMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class PointsExpirationTask {
    private final PointsDetailMapper pointsDetailMapper;
    private final UserPointsMapper userPointsMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    private static final String POINTS_EXPIRATION_QUEUE = "points:expiration:queue";

    @Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行
    // @PostConstruct
    @Transactional(rollbackFor = Exception.class)
    public void checkExpiringPoints() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime threeDaysLater = now.plusDays(3);

        // 查询即将过期的积分明细
        List<PointsDetail> expiringDetails = pointsDetailMapper.selectList(
            new LambdaQueryWrapper<PointsDetail>()
                .eq(PointsDetail::getStatus, 1)
                .between(PointsDetail::getExpireTime, now, threeDaysLater)
        );

        for (PointsDetail detail : expiringDetails) {
            // 发送过期提醒到Redis队列
            String message = String.format("用户ID: %d, 积分: %d, 过期时间: %s",
                detail.getUserId(), detail.getPoints(), detail.getExpireTime());
            redisTemplate.opsForList().rightPush(POINTS_EXPIRATION_QUEUE, message);

            log.info("积分过期提醒: {}", message);
        }

        // 处理已过期的积分
        List<PointsDetail> expiredDetails = pointsDetailMapper.selectList(
            new LambdaQueryWrapper<PointsDetail>()
                .eq(PointsDetail::getStatus, 1)
                .lt(PointsDetail::getExpireTime, now)
        );

        for (PointsDetail detail : expiredDetails) {
            // 更新积分明细状态
            detail.setStatus(0);
            pointsDetailMapper.updateById(detail);

            // 更新用户可用积分
            UserPoints userPoints = userPointsMapper.selectOne(
                new LambdaQueryWrapper<UserPoints>()
                    .eq(UserPoints::getUserId, detail.getUserId())
            );
            if (userPoints != null) {
                userPoints.setAvailablePoints(userPoints.getAvailablePoints() - detail.getPoints());
                userPointsMapper.updateById(userPoints);

                // 清除Redis缓存
                redisTemplate.delete("user:points:" + detail.getUserId());
            }

            log.info("积分已过期: 用户ID: {}, 积分: {}", detail.getUserId(), detail.getPoints());
        }
    }
} 